package com.alex.index.insert.nsfctest;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.UUID;
import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
import cn.hutool.crypto.symmetric.SymmetricCrypto;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch._types.FieldValue;
import co.elastic.clients.elasticsearch._types.SortOrder;
import co.elastic.clients.elasticsearch._types.aggregations.*;
import co.elastic.clients.elasticsearch._types.query_dsl.*;
import co.elastic.clients.elasticsearch.core.SearchRequest;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.elasticsearch.core.search.Hit;
import co.elastic.clients.json.JsonData;
import co.elastic.clients.json.JsonpMapper;
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
import com.alex.common.beans.ResultBean;
import com.alex.common.config.IndexConfig;
import com.alex.entity.AggsKeyValue;
import com.alex.entity.AggsKeyValueInt;
import com.alex.entity.ArticleEntity;
import com.alex.entity.PageListNfsc;
import com.alex.paramVo.ArticleSearchVo;
import com.alex.service.AllQueryBasicService;
import com.alex.utils.*;
import jakarta.json.stream.JsonGenerator;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.sql.SQLException;
import java.time.Year;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @Author: 葛成瑞
 * @Date: 2025/4/8 16:36
 */
@Slf4j
public class searchTest {

    @SneakyThrows
    public static void main(String[] args) {


        //
        ArticleSearchVo searchVo = new ArticleSearchVo();
        searchVo.setPage(1);
        searchVo.setLimit(20);
        searchVo.setPram("");
        searchVo.setShortFiled(1);
        searchVo.setShortOrder(1);
        searchVo.setAuthor("Chen, Youming");
        searchVo.setType("QF_Study_Cn_Pubmed");
        Query query = null;

        List<ArticleEntity> resultList = new ArrayList<>();
        if (StringUtil.isEmpty(searchVo.getPram())) {
            searchVo.setPram("");
            BoolQuery.Builder boolQuery = getBoolQueryNsfc(searchVo);
            query = boolQuery.build()._toQuery();
        }
        //排序字段 默认 1 相关度
        if (searchVo.getShortFiled() == null) {
            searchVo.setShortFiled(1);
        }
        //排序方式 默认 1 正序
        if (searchVo.getShortOrder() == null) {
            searchVo.setShortOrder(1);
        }
        String sorter = "";
        if (searchVo.getShortFiled() == 2) {
            sorter = "year";
        }
        if (searchVo.getShortFiled() == 3) {
            sorter = "citationquota";
        }
        if (searchVo.getShortFiled() == 4) {
            sorter = "jcr_if";
        }

        //获取 SearchRequest对象
        SearchRequest.Builder builder = new SearchRequest.Builder();

        List<String> includes = Stream.of("id", "title", "journal", "ab", "unit", "unit_dept", "pmid", "doi", "ut", "authors", "cn_ab", "year", "cn_ti", "jcr_if", "zkydalei", "cite", "jid",
                "keyword", "info",
                "citationquota", "auth").collect(Collectors.toList());
        //如果是写作助手返回回来的,增加返回字段
        builder.index(IndexConfig.CORE_INDEXNFSC);
        if (searchVo.getShortFiled() != 1) {
            String finalSorter = sorter;
            builder.sort(sortOptionsBuilder -> sortOptionsBuilder.field(fieldSortBuilder -> fieldSortBuilder.field(finalSorter).order(searchVo.getShortOrder() == 1 ? SortOrder.Asc : SortOrder.Desc)));
        }
        List<Integer> pageListIds = checkPage(searchVo.getPage(), searchVo.getLimit());

//        if (StringUtil.isEmpty(searchVo.getPram())) {
//            query = null;
//        }
        SearchRequest searchRequest = builder.query(query)
                .source(sourceConfigBuilder -> sourceConfigBuilder.filter(sourceFilterBuilder -> sourceFilterBuilder.includes(includes)))
                .highlight(highlightBuilder -> highlightBuilder.preTags("<span style=\"color:red\">").postTags("</span>")
                        .fields("title", highlightFieldBuilder -> highlightFieldBuilder.numberOfFragments(0).fragmentSize(1000))
                        .fields("cn_ti", highlightFieldBuilder -> highlightFieldBuilder.numberOfFragments(0).fragmentSize(1000))
                        .fields("ab", highlightFieldBuilder -> highlightFieldBuilder.numberOfFragments(0).fragmentSize(1000))
                        .fields("cn_ab", highlightFieldBuilder -> highlightFieldBuilder.numberOfFragments(0).fragmentSize(1000))

                )
                .trackTotalHits(k -> k.enabled(true))
                .from(pageListIds.get(0))
                .size(pageListIds.get(1))

                .build();


        //打印DSL
        printEsBySearchRequest(searchRequest);
        SearchResponse<ArticleEntity> response = EsClient.client.search(searchRequest, ArticleEntity.class);


        List<Hit<ArticleEntity>> hits = response.hits().hits();

        //处理返回结果的高亮
        for (Hit<ArticleEntity> hit : response.hits().hits()) {
            ArticleEntity source = hit.source();
            Map<String, List<String>> highlight = hit.highlight();
            highlight.forEach((k, v) -> {
                if (k.equals("title")) {
                    source.setTitle(v.get(0));
                } else if (k.equals("cn_ti")) {
                    source.setCn_ti(v.get(0));
                } else if (k.equals("ab")) {
                    StringBuilder stringBuilder = new StringBuilder();
                    for (String s : v) {
                        stringBuilder.append(s);
                    }
                    source.setAb(stringBuilder.toString());
                } else if (k.equals("cn_ab")) {
                    StringBuilder stringBuilder = new StringBuilder();
                    for (String s : v) {
                        stringBuilder.append(s);
                    }
                    source.setCn_ab(stringBuilder.toString());
                }
            });
        }
        //根据来源判断是否增加诚信信息
        if ("QF_Study_Cn_Pubmed".equalsIgnoreCase(searchVo.getType())) {

            for (Hit<ArticleEntity> hit : hits) {
                ArticleEntity source = hit.source();
                String cnTi = source.getCn_ti();
                if (cnTi != null) {
                    cnTi = cnTi.replace("ĺļ", "");
                    source.setCn_ti(cnTi);
                }
                resultList.add(source);
            }
        } else {
            System.out.println("非PM,直接返回,不去检索诚信信息");
            resultList = AllQueryBasicService.coventList(hits);
        }

        /**
         * 开始封装返回结果
         */
        long value = response.hits().total().value();
        System.out.println("命中数量_" + value);
        PageListNfsc<ArticleEntity> pageList = new PageListNfsc<>();
        pageList.setUuid(null);
        pageList.setTotalElements(value);
        for (ArticleEntity ArticleEntity_V2 : resultList) {
            if (StringUtil.isNotNull(ArticleEntity_V2.getUt())) {
                String ut = ArticleEntity_V2.getUt();
                ArticleEntity_V2.setUt(encryptionAid(ut));
            }
        }

        for (ArticleEntity articleEntityV2 : resultList) {
            articleEntityV2.setInfo(toTitleCase(articleEntityV2.getInfo()));
        }

        pageList.setList(resultList);
        pageList.setTotalPages((int) (value / searchVo.getLimit() < 1 ? 1 : (value / searchVo.getLimit()) + 1));//总页数
        pageList.setCurrentPage(searchVo.getPage());//当前页
        pageList.setPageSize(searchVo.getLimit());//每页显示条数


        /**
         * 中文 pubmed
         */
        if ("QF_Study_Cn_Pubmed".equalsIgnoreCase(searchVo.getType())) {
            pageList.setZkydalei(filter_LongNSFC(query, "zkydalei", 20));
//            pageList.setAuthor(filter_StrNSFC(query, "auth.keyword", 20));
            pageList.setKeyWord(filter_StrNSFC(query, "keyword.keyword", 20));
            pageList.setDrug(filter_StrNSFC(query, "drug.keyword", 20));
            pageList.setGene(filter_StrNSFC(query, "gene.keyword", 20));
            pageList.setPathway(filter_StrNSFC(query, "pathway.keyword", 20));
            pageList.setDisease(filter_StrNSFC(query, "disease.keyword", 20));
//            pageList.setUnitNew(filter_StrNSFCUnit(query, "unit.keyword", 20, searchVo.getUnitNew()));
            filter_StrNSFCUnit(pageList, query, "authors.units", 20, searchVo.getAuthor(), searchVo.getUnitNew(), searchVo.getDept());
//            pageList.setUnitNew(filter_StrNSFCUnit(pageList,query, "authors.units", 20, searchVo.getAuthor(), searchVo.getUnitNew(),searchVo.getDept()));
//            pageList.setDept(filter_StrNSFCDEPT(query, "dept.keyword", 20, searchVo.getDept()));
//            pageList.setDept(filter_StrNSFCDEPT(query, "authors.depts", 20, searchVo.getDept()));
            pageList.setJournal(filter_StrNSFC(query, "journal.keyword", 20));
            pageList.setYear(filter_LongNSFCYear(query, "year", 20));
        }

        String uuid = UUID.randomUUID().toString();
        RedisUtil.saveObject(uuid, searchVo);
        pageList.setUuid(uuid);
        System.out.println(pageList);


    }

    public static String toTitleCase(String input) {
        StringBuilder titleCase = new StringBuilder();
        boolean nextTitleCase = true;
        for (char c : input.toCharArray()) {
            if (Character.isSpaceChar(c)) {
                nextTitleCase = true;
            } else if (nextTitleCase) {
                c = Character.toTitleCase(c);
                nextTitleCase = false;
            } else {
                c = Character.toLowerCase(c);
            }
            titleCase.append(c);
        }
        return titleCase.toString();
    }

    public static List<AggsKeyValue> filter_LongNSFCYear(Query query, String filter, Integer count) throws Exception {
        SearchResponse<ArticleEntity> response = EsClient.client.search(searchRequestBuilder -> searchRequestBuilder
                        .index(IndexConfig.CORE_INDEXNFSC).query(query)
                        .aggregations("my_aggre", aggregationBuilder -> aggregationBuilder
                                .terms(termsAggregationBuilder -> termsAggregationBuilder
                                        .field(filter).size(count)
                                )
                        ).size(0),
                ArticleEntity.class);
        List<AggsKeyValue> list = new ArrayList<>();
        List<LongTermsBucket> array = response.aggregations().get("my_aggre").lterms().buckets().array();

        List<AggsKeyValueInt> resultList = new ArrayList<>();
        List<AggsKeyValue> res = new ArrayList<>();
        array.forEach(i -> {
            Long key = i.key();
            long value = i.docCount();
//            resultList.add(new AggsKeyValue("" + key, value));
            if (key != null) {
                int year = 0;
                try {
                    year = Integer.parseInt(key.toString());
                } catch (Exception e) {
                }
                if (year > 0) {
                    resultList.add(new AggsKeyValueInt(key, value));
                }
            }
        });
        List<AggsKeyValueInt> collect = resultList.stream().sorted(Comparator.comparing(AggsKeyValueInt::getKey).reversed()).collect(Collectors.toList());
        for (AggsKeyValueInt aggsKeyValueInt : collect) {
            AggsKeyValue s = new AggsKeyValue(aggsKeyValueInt.getKey() + "", aggsKeyValueInt.getValue());
            res.add(s);
        }


        return res;
    }

    public static String encryptionAid(String articleId) {
        byte[] key = "qf3.1415@123@456".getBytes(StandardCharsets.UTF_8);
        SymmetricCrypto aes = new SymmetricCrypto(SymmetricAlgorithm.AES, key);
        String encryptHex = aes.encryptHex("" + articleId);
        return encryptHex;
    }

    public static List<AggsKeyValue> filter_StrNSFC(Query query, String filter, Integer count) throws Exception {
        ElasticsearchClient client = EsClient.client();
        SearchResponse<ArticleEntity> response = EsClient.client.search(searchRequestBuilder -> searchRequestBuilder
                        .index(IndexConfig.CORE_INDEXNFSC)
                        .query(query)
                        .aggregations("my_aggre", aggregationBuilder -> aggregationBuilder
                                .terms(termsAggregationBuilder -> termsAggregationBuilder
                                        .field(filter).size(count)
                                )
                        ),
                ArticleEntity.class);
        List<AggsKeyValue> list = new ArrayList<>();
        for (StringTermsBucket bucket : response.aggregations().get("my_aggre").sterms().buckets().array()) {
            long value = bucket.docCount();
            if (StringUtil.isNotNull(bucket.key().stringValue())) {
                if (filter.equals("gene.keyword")) {
                    list.add(new AggsKeyValue(bucket.key().stringValue().toUpperCase(), value));
                } else {
                    list.add(new AggsKeyValue(bucket.key().stringValue(), value));
                }

            }

        }

        List<AggsKeyValue> collect = list.stream().filter(i -> StringUtil.isNotNull(i)).sorted(Comparator.comparing(AggsKeyValue::getValue).reversed()).collect(Collectors.toList());
        return collect;
    }

    //放在一起处理 作者 单位 部门数量信息
    public static List<AggsKeyValue> filter_StrNSFCUnit(PageListNfsc<ArticleEntity> pageList,
                                                        Query query,
                                                        String filter,
                                                        Integer count,
                                                        String author,
                                                        String unit,
                                                        String dept) throws Exception {
        ElasticsearchClient client = EsClient.client();
        SearchResponse<ArticleEntity> response = EsClient.client.search(searchRequestBuilder -> searchRequestBuilder
                        .index(IndexConfig.CORE_INDEXNFSC)
                        .query(query).aggregations("author_facet", a -> a
                        .nested(n -> n.path("authors")) // 外层 nested 聚合
                        .aggregations("filter_author", a2 -> a2
//                                .filter(f -> f // filter 聚合
                                        .terms(t -> t
                                                .field("authors.name")
                                                .size(count)
                                        )
//                                )
                                        .aggregations("units", a3 -> a3 // units 聚合
                                        .terms(t -> t
                                                .field("authors.units")
                                                .size(count)
                                        )
                                        .aggregations("distinct_articles", a4 -> a4
                                                .cardinality(c -> c.field("id"))
                                        )
                                )
                                .aggregations("depts", a3 -> a3 // depts 聚合
                                        .terms(t -> t
                                                .field("authors.depts")
                                                .size(count)
                                        )
                                        .aggregations("distinct_articles", a4 -> a4
                                                .cardinality(c -> c.field("id"))
                                        )
                                )
                        )
                ), ArticleEntity.class);

        // ceshi
        // 构建 units 的 terms 聚合及其 cardinality 子聚合
//        TermsAggregationBuilder unitsTerms = AggregationBuilders.terms("units")
//                .field("authors.units")
//                .size(100);
//        CardinalityAggregationBuilder unitsCardinality = AggregationBuilders.cardinality("distinct_articles")
//                .field("article_id");
//        unitsTerms.subAggregation(unitsCardinality);
        // 测试分支

        List<AggsKeyValue> AUlist = new ArrayList<>();
        List<AggsKeyValue> unitlist = new ArrayList<>();
        List<AggsKeyValue> deptlist = new ArrayList<>();
        Aggregate authorFacet = response.aggregations().get("author_facet");
        Buckets<StringTermsBucket> filterAuthor = authorFacet.nested().aggregations().get("filter_author").sterms().buckets();
        filterAuthor.array().forEach(bucket -> {
            FieldValue key = bucket.key();
            if (StringUtil.isNotNull(key.stringValue())) {
                String name = key.stringValue();
                long l = bucket.docCount();
                AUlist.add(new AggsKeyValue(name, l));
                Aggregate unitsAgg = bucket.aggregations().get("units");
                Buckets<StringTermsBucket> unitsBuckets = unitsAgg.sterms().buckets();
                unitsBuckets.array().forEach(unitsBucket -> {
                    FieldValue unitsKey = unitsBucket.key();
                    String unitsName = unitsKey.stringValue();
                    long unitCount = unitsBucket.docCount();
                    unitlist.add(new AggsKeyValue(unitsName, unitCount));
                });
                Aggregate deptsAgg = bucket.aggregations().get("depts");
                Buckets<StringTermsBucket> deptsBuckets = deptsAgg.sterms().buckets();
                deptsBuckets.array().forEach(deptsBucket -> {
                    FieldValue deptsKey = deptsBucket.key();
                    long deptSize = deptsBucket.docCount();
                    deptlist.add(new AggsKeyValue(deptsKey.stringValue(), deptSize));
                });
            }
        });


        List<AggsKeyValue> collectau = AUlist.stream().filter(i -> StringUtil.isNotNull(i)).sorted(Comparator.comparing(AggsKeyValue::getValue).reversed()).collect(Collectors.toList());
        List<AggsKeyValue> collectunit = unitlist.stream().filter(i -> StringUtil.isNotNull(i)).sorted(Comparator.comparing(AggsKeyValue::getValue).reversed()).collect(Collectors.toList());
        List<AggsKeyValue> collectdept = deptlist.stream().filter(i -> StringUtil.isNotNull(i)).sorted(Comparator.comparing(AggsKeyValue::getValue).reversed()).collect(Collectors.toList());


        if (StringUtil.isNotNull(author)) {
            collectau = collectau.stream().filter(i -> i.getKey().contains(author)).collect(Collectors.toList());
        }
        if (StringUtil.isNotNull(unit)) {
            collectunit = collectunit.stream().filter(i -> i.getKey().contains(unit)).collect(Collectors.toList());
        }
        if (StringUtil.isNotNull(dept)) {
            collectdept = collectdept.stream().filter(i -> i.getKey().contains(dept)).collect(Collectors.toList());
        }
        pageList.setAuthor(collectau);
        pageList.setUnitNew(collectunit);
        pageList.setDept(collectdept);

        return collectau;
    }

    public static List<AggsKeyValue> filter_StrNSFCDEPT(Query query, String filter, Integer count, String dept) throws Exception {
        ElasticsearchClient client = EsClient.client();
        SearchResponse<ArticleEntity> response = client.search(searchRequestBuilder -> searchRequestBuilder
                        .index(IndexConfig.CORE_INDEXNFSC)
                        .query(query)
                        .aggregations("my_aggre", aggregationBuilder -> aggregationBuilder
                                .terms(termsAggregationBuilder -> termsAggregationBuilder
                                        .field(filter).size(count)
                                )
                        ),
                ArticleEntity.class);
        List<AggsKeyValue> list = new ArrayList<>();
        for (StringTermsBucket bucket : response.aggregations().get("my_aggre").sterms().buckets().array()) {
            long value = bucket.docCount();
            list.add(new AggsKeyValue(bucket.key().stringValue(), value));
        }

        List<AggsKeyValue> collect = list.stream().filter(i -> StringUtil.isNotNull(i)).sorted(Comparator.comparing(AggsKeyValue::getValue).reversed()).collect(Collectors.toList());
        if (StringUtil.isNotNull(dept)) {
            collect = collect.stream().filter(i -> i.getKey().contains(dept)).collect(Collectors.toList());
        }
        return collect;
    }

    public static List<AggsKeyValue> filter_LongNSFC(Query query, String filter, Integer count) throws Exception {
        ElasticsearchClient client = EsClient.client();
        SearchResponse<ArticleEntity> response = EsClient.client.search(searchRequestBuilder -> searchRequestBuilder
                        .index(IndexConfig.CORE_INDEXNFSC).query(query)
                        .aggregations("my_aggre", aggregationBuilder -> aggregationBuilder
                                .terms(termsAggregationBuilder -> termsAggregationBuilder
                                        .field(filter).size(count)
                                )
                        ).size(0),
                ArticleEntity.class);
        List<AggsKeyValue> list = new ArrayList<>();
        List<LongTermsBucket> array = response.aggregations().get("my_aggre").lterms().buckets().array();

        List<AggsKeyValue> resultList = new ArrayList<>();
        array.forEach(i -> {
            long key = i.key();
            long value = i.docCount();
            resultList.add(new AggsKeyValue("" + key, value));
        });
        List<AggsKeyValue> collect = resultList.stream().sorted(Comparator.comparing(AggsKeyValue::getValue)).collect(Collectors.toList());


        return collect;
    }


    public static BoolQuery.Builder getBoolQueryNsfc(ArticleSearchVo searchVo) throws SQLException, IOException {
        BoolQuery.Builder allQueryBuilder = new BoolQuery.Builder();

        //特殊情况一 用户检索词中含有&符号,将其替换成#z#a#f#n#fd#
        String searchWord = searchVo.getPram();
        if (searchWord.startsWith("id=")) {//aid
            searchWord = searchWord.replace("id=", "");
            if (CheckUtil.isNumberRange(searchWord)) {
                String[] split = searchWord.split(",");
                List<FieldValue> values = new ArrayList<>();
                for (String id : split) {
                    values.add(FieldValue.of(id));
                }
                Query idsQuery = TermsQuery.of(t -> t.field("aid").terms(new TermsQueryField.Builder().value(values).build()))._toQuery();
                allQueryBuilder.must(idsQuery);
            }

        } else if (searchWord.startsWith("pmid=")) {
            searchWord = searchWord.replace("pmid=", "");
            if (CheckUtil.isNumberRange(searchWord)) {
                String[] split = searchWord.split(",");
                List<FieldValue> values = new ArrayList<>();
                for (String id : split) {
                    values.add(FieldValue.of(id));
                }
                Query idsQuery = TermsQuery.of(t -> t.field("pmid").terms(new TermsQueryField.Builder().value(values).build()))._toQuery();
                allQueryBuilder.must(idsQuery);
            }
        } else if (CheckUtil.isNumber(searchWord)) {
            //判断是不是pmid
            searchWord = searchWord.replaceAll("\\[pmid\\]", "");
            searchWord = searchWord.replaceAll("\\[PMID\\]", "");
            String finalPram1 = searchWord;
            TermQuery query = TermQuery.of(i -> i.field("pmid").value(k -> k.stringValue(finalPram1)));
            allQueryBuilder.must(query._toQuery());
            return allQueryBuilder;
        }

        /**
         * 如果是课题思路助手 和高分选题 只要pm数据
         */
        if (searchVo.getType() != null) {
            if (searchVo.getType().equalsIgnoreCase("QF_Study_Topic_Idea_Assistant") || searchVo.getType().equalsIgnoreCase("HIGH_SCORING_TOPICS")) {
                allQueryBuilder.mustNot(TermQuery.of(i -> i.field("pmid").value(0))._toQuery());
            }
        }

        /**
         * 影响因子过滤
         */
        if (StringUtil.isNotNull(searchVo.getJif())) {
            String[] strings = searchVo.getJif().split("###");
            BoolQuery.Builder builder = new BoolQuery.Builder();
            for (String string : strings) {
                String[] split = string.split("_");
                System.out.println("多选影响因子左侧_" + split[0]);
                System.out.println("多选影响因子右侧_" + split[1]);
                System.out.println("--------------");
                Query rangeQuery = RangeQuery.of(i -> i.field("jcr_if").gte(JsonData.fromJson(split[0] + ".0")).lte(JsonData.fromJson(split[1] + ".0")))._toQuery();
                builder.should(rangeQuery);
            }
            allQueryBuilder.must(builder.build()._toQuery());
        }
        /**
         * 年份过滤
         */
        if (CheckUtil.isNotNull(searchVo.getYears())) {
            String pubyear = searchVo.getYears();
            if (pubyear.contains("_")) {
                String[] split = pubyear.split("_");
                Query rangeQuery = RangeQuery.of(i -> i.field("year").gte(JsonData.fromJson(split[0] + ".0")).lte(JsonData.fromJson(split[1] + ".0")))._toQuery();
                allQueryBuilder.must(rangeQuery);
            } else {
                Query toQuery = TermQuery.of(i -> i.field("year").value(pubyear))._toQuery();
                allQueryBuilder.must(toQuery);
            }

        }

        /**
         * 中科院分区
         */
        if (null != searchVo.getZkyDaLei()) {
            List<String> list = covent(searchVo.getZkyDaLei());
            List<FieldValue> values = new ArrayList<>();
            for (String id : list) {
                values.add(FieldValue.of(id));
            }
            Query idsQuery = TermsQuery.of(t -> t.field("zkydalei").terms(new TermsQueryField.Builder().value(values).build()))._toQuery();
            allQueryBuilder.must(idsQuery);
        }
        /**
         * JCR分区
         */
        if (null != searchVo.getJcrFenQu()) {
            List<String> list = covent(searchVo.getJcrFenQu());
            List<FieldValue> values = new ArrayList<>();
            for (String id : list) {
                values.add(FieldValue.of(id));
            }
            Query idsQuery = TermsQuery.of(t -> t.field("jcr_quartile").terms(new TermsQueryField.Builder().value(values).build()))._toQuery();
            allQueryBuilder.must(idsQuery);
        }

        /**
         * 近三年
         */
        if (null != searchVo.getThYears() && searchVo.getThYears() == 1) {

            // 获取当前年份
            int currentYear = Year.now().getValue();

            // 计算三年前的年份
            int yearThreeYearsAgo = currentYear - 3;

            Query rangeQuery = RangeQuery.of(i -> i.field("year").gte(JsonData.fromJson(yearThreeYearsAgo + ".0")).lte(JsonData.fromJson(currentYear + ".0")))._toQuery();
            allQueryBuilder.must(rangeQuery);
        }

        /**
         * 年份过滤 课题思路助手
         */
        if (StringUtil.isNotNull(searchVo.getYear())) {
            List<String> list = covent(searchVo.getYear());
            List<FieldValue> values = new ArrayList<>();
            for (String id : list) {
                values.add(FieldValue.of(id));
            }
            Query idsQuery = TermsQuery.of(t -> t.field("year").terms(new TermsQueryField.Builder().value(values).build()))._toQuery();
            allQueryBuilder.must(idsQuery);
        }
        /**
         * 年份过滤 结题基金论文
         */
        if (StringUtil.isNotNull(searchVo.getFundYears())) {
            List<String> list = covent(searchVo.getFundYears());
            List<FieldValue> values = new ArrayList<>();
            for (String id : list) {
                values.add(FieldValue.of(id));
            }
            Query idsQuery = TermsQuery.of(t -> t.field("year").terms(new TermsQueryField.Builder().value(values).build()))._toQuery();
            allQueryBuilder.must(idsQuery);
        }
        /**
         * 是否是六大刊
         */
        if (null != searchVo.getIsCns()) {
            Query query = TermQuery.of(i -> i.field("is_cns").value(searchVo.getIsCns()))._toQuery();
            allQueryBuilder.must(query);
        }
        /**
         * 期刊过滤
         */
        if (null != searchVo.getJournal()) {
            List<String> list = covent(searchVo.getJournal());
            List<FieldValue> values = new ArrayList<>();
            for (String id : list) {
                values.add(FieldValue.of(id));
            }
            Query idsQuery = TermsQuery.of(t -> t.field("journal.keyword").terms(new TermsQueryField.Builder().value(values).build()))._toQuery();
            allQueryBuilder.must(idsQuery);
        }

        /**
         * 作者过滤
         */
        if (null != searchVo.getAuthor()) {
            List<String> list = covent(searchVo.getAuthor());
            List<FieldValue> values = new ArrayList<>();
            for (String id : list) {
                values.add(FieldValue.of(id));
            }
            NestedQuery nestedQuery = NestedQuery.of(n -> n.path("authors").query(q -> q.terms(t -> t.field("authors.name").terms(new TermsQueryField.Builder().value(values).build()))));
            allQueryBuilder.must(nestedQuery._toQuery());
        }

        // 2024年10月16日14:01:40 现在有个问题是关于过滤 加入一篇文章里面 有单位 a b  分别对应的 部门 c d 也就是合并切来 有
        // a_c b_d 如果拆开计算 会导致 假如检索结果 出现了 a 单位 那么也会出现 c d 部门 如果点击了过滤会导致没数据 加入点击了一个 a_d
        // 就出现 0  所以在过滤返回左侧时候就需要判断到所有单位对应的部门进行处理

        //单位过滤 unit 葛成瑞新增
        if (StringUtil.isNotNull(searchVo.getUnitNew())) {
            log.info("过滤单位+" + searchVo.getUnitNew());
            List<String> list = covent(searchVo.getUnitNew());
            List<FieldValue> values = new ArrayList<>();
            for (String id : list) {
                values.add(FieldValue.of(id));
            }
            NestedQuery nestedQuery = NestedQuery.of(n -> n.path("authors").query(q -> q.terms(t -> t.field("authors.units").terms(new TermsQueryField.Builder().value(values).build()))));
//            Query idsQuery = TermsQuery.of(t -> t.field("authors.units").terms(new TermsQueryField.Builder().value(values).build()))._toQuery();
            allQueryBuilder.must(nestedQuery._toQuery());
        }

        //部门过滤 dept 葛成瑞新增
        if (StringUtil.isNotNull(searchVo.getDept())) {
            log.info("过滤部门+" + searchVo.getDept());
            List<String> list = covent(searchVo.getDept());
            List<FieldValue> values = new ArrayList<>();
            for (String id : list) {
                values.add(FieldValue.of(id));
            }
            NestedQuery nestedQuery = NestedQuery.of(n -> n.path("authors").query(q -> q.terms(t -> t.field("authors.depts").terms(new TermsQueryField.Builder().value(values).build()))));
            allQueryBuilder.must(nestedQuery._toQuery());
//            Query idsQuery = TermsQuery.of(t -> t.field("authors.depts").terms(new TermsQueryField.Builder().value(values).build()))._toQuery();
//            allQueryBuilder.must(idsQuery);
        }

        // 单位部门过滤 新增
//        if (StringUtil.isNotNull(searchVo.getUnitNew()) && StringUtil.isNotNull(searchVo.getDept())) {
//            searchVo.setUnitDept(searchVo.getUnitNew() + "_" + searchVo.getDept());
//            log.info("过滤单位部门+" + searchVo.getUnitDept());
//            List<String> list = covent(searchVo.getUnitDept());
//            List<FieldValue> values = new ArrayList<>();
//            for (String id : list) {
//                values.add(FieldValue.of(id));
//            }
//            Query wildCard = WildcardQuery.of(i -> i.field("unit_dept.wildcard").value(searchVo.getUnitDept()))._toQuery();
//            allQueryBuilder.should(wildCard);
//        }

        /**
         * 机构过滤
         */
        if (null != searchVo.getUnit()) {
            List<String> list = covent(searchVo.getUnit());
            List<FieldValue> values = new ArrayList<>();
            for (String id : list) {
                values.add(FieldValue.of(id));
            }
            Query idsQuery = TermsQuery.of(t -> t.field("cn_unit.keyword").terms(new TermsQueryField.Builder().value(values).build()))._toQuery();
            allQueryBuilder.must(idsQuery);
        }
        /**
         * 国家过滤
         */
        if (null != searchVo.getCountry()) {
            List<String> list = covent(searchVo.getCountry());
            List<FieldValue> values = new ArrayList<>();
            for (String id : list) {
                values.add(FieldValue.of(id));
            }
            Query idsQuery = TermsQuery.of(t -> t.field("cn_country.keyword").terms(new TermsQueryField.Builder().value(values).build()))._toQuery();
            allQueryBuilder.must(idsQuery);
            allQueryBuilder.mustNot(TermQuery.of(i -> i.field("cn_country.keyword").value(""))._toQuery());
        }


        /**
         * 关键词过滤 2024年11月2日15:06:56 新增
         *
         */
        if (null != searchVo.getKeyWord()) {
            List<String> list = covent(searchVo.getKeyWord());
            BoolQuery.Builder keywordBool = new BoolQuery.Builder();
            for (String s : list) {
                keywordBool.must(TermQuery.of(i -> i.field("keyword.keyword").value(s))._toQuery());
            }
            allQueryBuilder.must(keywordBool.build()._toQuery());
        }

        /**
         * 文献类型
         */
        if (null != searchVo.getPt()) {
            List<String> list = covent(searchVo.getPt());
            List<FieldValue> values = new ArrayList<>();
            for (String id : list) {
                values.add(FieldValue.of(id));
            }
            Query idsQuery = TermsQuery.of(t -> t.field("pt.keyword").terms(new TermsQueryField.Builder().value(values).build()))._toQuery();
            allQueryBuilder.must(idsQuery);
        }
        /**
         * 疾病
         */
        if (CheckUtil.isNotNull(searchVo.getDisease())) {

            List<String> list = covent(searchVo.getDisease());
            List<FieldValue> values = new ArrayList<>();
            for (String id : list) {
                values.add(FieldValue.of(id));
            }
            Query idsQuery = TermsQuery.of(t -> t.field("disease.keyword").terms(new TermsQueryField.Builder().value(values).build()))._toQuery();
            allQueryBuilder.must(idsQuery);
        }
        /**
         * 基因
         */
        if (CheckUtil.isNotNull(searchVo.getGene())) {

            List<String> list = covent(searchVo.getGene());
            List<FieldValue> values = new ArrayList<>();
            for (String id : list) {
                values.add(FieldValue.of(id));
            }
            Query idsQuery = TermsQuery.of(t -> t.field("gene.keyword").terms(new TermsQueryField.Builder().value(values).build()))._toQuery();
            allQueryBuilder.must(idsQuery);
        }
        /**
         * 通路
         */
        if (CheckUtil.isNotNull(searchVo.getPathway())) {

            List<String> list = covent(searchVo.getPathway());
            List<FieldValue> values = new ArrayList<>();
            for (String id : list) {
                values.add(FieldValue.of(id));
            }
            Query idsQuery = TermsQuery.of(t -> t.field("pathway.keyword").terms(new TermsQueryField.Builder().value(values).build()))._toQuery();
            allQueryBuilder.must(idsQuery);
        }
        /**
         * 药物
         */
        if (CheckUtil.isNotNull(searchVo.getDrug())) {

            List<String> list = covent(searchVo.getDrug());
            List<FieldValue> values = new ArrayList<>();
            for (String id : list) {
                values.add(FieldValue.of(id));
            }
            Query idsQuery = TermsQuery.of(t -> t.field("drug.keyword").terms(new TermsQueryField.Builder().value(values).build()))._toQuery();
            allQueryBuilder.must(idsQuery);
        }
        /**
         * 是否是中国人
         */
        if (searchVo.getIsChina() != null) {
            if (searchVo.getIsChina() == 1) {
                Query idsQuery = TermQuery.of(t -> t.field("is_china").value(1))._toQuery();
                allQueryBuilder.must(idsQuery);
            } else if (searchVo.getIsChina() == 0) {
                Query idsQuery = TermQuery.of(t -> t.field("is_china").value(0))._toQuery();
                allQueryBuilder.must(idsQuery);
            }
        }
        return allQueryBuilder;
    }


    /**
     * 分页
     *
     * @param page
     * @param limit
     * @return
     */
    public static List<Integer> checkPage(Integer page, Integer limit) {
        if (page == null) page = 0;
        if (limit == null) limit = 10;
        List<Integer> list = new ArrayList<>();

        list.add((page - 1) * limit);
        //list.add(((page - 1) * limit) + limit);
        list.add(limit);
        return list;
    }

    public static List<String> covent(String s) {
        if (CheckUtil.isNull(s)) {
            return new ArrayList<>();
        } else {
            return Convert.toList(String.class, s.split("###"));
        }
    }

    /**
     * 打印DLS
     *
     * @param searchRequest
     */
    public static void printEsBySearchRequest(SearchRequest searchRequest) {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        JsonpMapper mapper = new JacksonJsonpMapper();
        JsonGenerator generator = mapper.jsonProvider().createGenerator(byteArrayOutputStream);
        mapper.serialize(searchRequest, generator);
        generator.close();
        System.out.println("打印的DSL___");
        System.out.println(byteArrayOutputStream.toString());

    }

}


